1 00:00:00,320 --> 00:00:04,940 Alrighty, in this lecture, we're going to be scripting the system that will set up and be responsible 2 00:00:04,940 --> 00:00:07,460 for handling our players spectating system. 3 00:00:07,460 --> 00:00:12,200 So to do that, we're going to have to go into starter player and go into starter player scripts and 4 00:00:12,200 --> 00:00:15,650 go ahead and open up the handler for our main guy. 5 00:00:15,770 --> 00:00:22,400 From this point we can scroll down and if you remember, when we are told that we have died and we display 6 00:00:22,400 --> 00:00:27,980 the died frame on the screen, we need to go ahead and call our start spectating function to start spectating. 7 00:00:27,980 --> 00:00:32,030 Currently, this function is empty, so we need to go ahead and fill out the functionality for this. 8 00:00:32,030 --> 00:00:36,980 So to start spectating, the first thing that we need to do is refer to our spectate frame and set the 9 00:00:36,980 --> 00:00:38,180 visibility equal to true. 10 00:00:38,180 --> 00:00:40,400 So that way it appears on our screen. 11 00:00:40,400 --> 00:00:44,960 The next thing that we would probably have to do is enable night vision on our screen. 12 00:00:44,960 --> 00:00:47,210 So that way we are able to see in the dark. 13 00:00:47,210 --> 00:00:53,120 So if you remember we have our camera manipulation bindable that we have inside of, I believe, replicated 14 00:00:53,120 --> 00:00:58,790 storage that we can use to communicate with our camera manipulation handler to go ahead and enable night 15 00:00:58,790 --> 00:00:59,240 vision. 16 00:00:59,240 --> 00:01:04,760 So if you remember here we have our camera manipulation Bindable, which listens to the exact same function 17 00:01:04,760 --> 00:01:05,270 here. 18 00:01:05,270 --> 00:01:10,370 And we have the action to be able to enable night vision on the client. 19 00:01:10,370 --> 00:01:14,570 So that means we're going to have to make a reference to this bindable inside of our main guy handler, 20 00:01:14,570 --> 00:01:20,270 so we can go up and we can go ahead and call this manipulation camera Bindable. 21 00:01:20,270 --> 00:01:26,900 That's in replicated storage, dot events, dot bindable, dot camera manipulation or manipulate camera. 22 00:01:26,900 --> 00:01:30,890 And we're also going to go ahead and get our camera manipulation enum as well. 23 00:01:30,890 --> 00:01:38,810 So camera manipulation enum that's in replicated storage, dot modules, dot enums dot camera manipulation 24 00:01:38,810 --> 00:01:39,410 enum. 25 00:01:39,800 --> 00:01:45,410 And inside of our start spectating function we're going to use the manipulation camera Bindable to fire 26 00:01:45,410 --> 00:01:50,840 and let our local script know that we would like to use the camera manipulation enum action to client 27 00:01:50,840 --> 00:01:52,910 of toggle night Vision. 28 00:01:53,990 --> 00:01:58,850 And remember we have to pass a boolean called Set on and we want it to be equal to true. 29 00:01:58,850 --> 00:02:02,510 That way we are enabling our night vision from this point. 30 00:02:02,510 --> 00:02:07,850 The next thing we would need to do is actually make sure that there are players on our map to spectate, 31 00:02:07,850 --> 00:02:13,580 so we could create a function to get all of the alive players or the players that we can spectate. 32 00:02:13,580 --> 00:02:16,580 So we can call this function get alive players. 33 00:02:16,730 --> 00:02:21,530 And we would refer to our alive team and get all of the players on that team. 34 00:02:21,530 --> 00:02:25,880 So we're going to have to make a reference to the team service up here. 35 00:02:27,070 --> 00:02:28,780 And then we could go back down. 36 00:02:30,000 --> 00:02:35,730 And from here, all we need to do is return all of the players that are on our alive team. 37 00:02:37,940 --> 00:02:44,120 So we can go ahead and get all of our live players from our Get Alive players function. 38 00:02:44,120 --> 00:02:49,760 And as long as the number of alive players is greater than zero, then we can start spectating. 39 00:02:49,760 --> 00:02:55,280 So that means we're going to have to make a reference to our camera and change some properties inside 40 00:02:55,280 --> 00:02:56,030 of our camera. 41 00:02:56,030 --> 00:02:58,970 And this is because we don't want our camera to be stuck in first person. 42 00:02:58,970 --> 00:03:00,980 We actually want to zoom the camera out. 43 00:03:00,980 --> 00:03:05,990 So that way our players can actually look around the map and rotate our camera around the players that 44 00:03:05,990 --> 00:03:06,860 they're spectating. 45 00:03:06,860 --> 00:03:12,980 So let's also go back up here and we can go ahead and create a variable to refer to our current camera. 46 00:03:12,980 --> 00:03:15,260 And that's in the workspace dot current camera. 47 00:03:15,260 --> 00:03:18,620 And I'll just call this current cam just to make it a little shorter. 48 00:03:20,320 --> 00:03:25,390 And while a live players is greater than zero, then we're going to refer to our current cam and set 49 00:03:25,390 --> 00:03:29,950 the camera type equal to the enum dot camera type of custom. 50 00:03:29,950 --> 00:03:34,540 That way our players can actually control the camera, and we're also going to set on our local player 51 00:03:34,570 --> 00:03:37,720 a property called Camera Mode by default. 52 00:03:37,720 --> 00:03:39,640 If you remember, we're stuck in first person. 53 00:03:39,640 --> 00:03:45,040 So we need to change this camera mode to the enum dot camera mode of classic. 54 00:03:45,040 --> 00:03:47,710 That way players aren't stuck inside of first person. 55 00:03:47,710 --> 00:03:52,510 From this point, we're going to use our manipulation camera bindable again and fire, and we're going 56 00:03:52,510 --> 00:03:56,080 to use the camera manipulation enum dot two client. 57 00:03:56,080 --> 00:04:01,480 And we want to give the action of setting the camera occlusion mode, because while we're spectating, 58 00:04:01,480 --> 00:04:04,780 we don't want our camera to be stuck, you know, inside of parts. 59 00:04:04,780 --> 00:04:09,670 Because for example, if the player were trying to spectate is like, let's say inside of a locker, 60 00:04:09,670 --> 00:04:13,960 well, our camera is going to be stuck colliding with the walls of the locker, and we're not going 61 00:04:13,960 --> 00:04:16,690 to really have a good view of the map or of our player. 62 00:04:16,690 --> 00:04:21,490 So we need to change the occlusion mode of our camera to a different one, and the mode that we would 63 00:04:21,490 --> 00:04:22,420 like to change it for. 64 00:04:22,420 --> 00:04:25,330 Remember, we have to pass a table with the occlusion mode. 65 00:04:26,130 --> 00:04:31,890 And that's going to be the enum.dev camera occlusion mode dot Invisi cam. 66 00:04:32,760 --> 00:04:38,430 And if we actually read that again, let me retype that in Physicam any objects between the camera and 67 00:04:38,430 --> 00:04:40,980 its subject become translucent locally. 68 00:04:41,010 --> 00:04:45,810 So this means our camera is able to pass through objects, and we can actually see our player through 69 00:04:45,810 --> 00:04:48,960 different parts because those parts become slightly transparent. 70 00:04:49,260 --> 00:04:55,050 So when we give this action to our camera manipulation handler, if we go ahead and look here, we're 71 00:04:55,140 --> 00:04:58,710 going to change the camera occlusion mode to whatever. 72 00:04:58,710 --> 00:05:00,180 And we get that occlusion mode. 73 00:05:00,180 --> 00:05:05,610 And then we use our camera manipulation event and fire to the server to change the camera occlusion 74 00:05:05,610 --> 00:05:09,930 mode for us, because we aren't able to change the camera occlusion mode from the client, we have to 75 00:05:09,930 --> 00:05:10,890 do it from the server. 76 00:05:10,890 --> 00:05:16,020 So that means we're going to have to create or script the functionality for listening to our manipulation 77 00:05:16,020 --> 00:05:16,890 camera event. 78 00:05:17,280 --> 00:05:19,950 So we can go ahead and do that inside of server script service. 79 00:05:19,950 --> 00:05:23,040 We'll go into the server and we'll open up one of these services. 80 00:05:23,040 --> 00:05:24,930 We could do it from our player join service. 81 00:05:24,930 --> 00:05:27,030 That would probably be the easiest. 82 00:05:27,700 --> 00:05:34,570 So inside of here we can make a reference to our manipulate camera event and that's inside of replicated 83 00:05:34,570 --> 00:05:37,240 storage, dot events, dot remotes, dot manipulate camera. 84 00:05:37,240 --> 00:05:41,320 And we're also going to make a reference to the camera manipulation enum. 85 00:05:41,320 --> 00:05:46,810 So we'll acquire from replicated storage dot modules, dot enums dot camera manipulation enum. 86 00:05:47,380 --> 00:05:50,650 And then we can go down to our initialize function. 87 00:05:50,650 --> 00:05:52,750 And we can go ahead and listen to this event. 88 00:05:52,750 --> 00:05:56,890 So manipulate cam event dot on server event. 89 00:05:56,890 --> 00:05:59,320 And we want to connect a Lambda function to this. 90 00:05:59,320 --> 00:06:04,030 Get the player that fired this event, get the action they wish for us to do and the arguments to go 91 00:06:04,030 --> 00:06:05,140 with that action. 92 00:06:05,230 --> 00:06:10,060 And the only action we care about in here is changing the player's occlusion mode. 93 00:06:10,060 --> 00:06:13,390 But we don't want to give any exploiters the ability to do this. 94 00:06:13,390 --> 00:06:17,830 So the first thing we want to check is to make sure that the player is actually on the dead team. 95 00:06:17,830 --> 00:06:19,510 So we know they're spectating. 96 00:06:19,510 --> 00:06:23,050 So let's go ahead and make a reference to the team service up here. 97 00:06:25,640 --> 00:06:27,290 And then we can go back down. 98 00:06:28,380 --> 00:06:34,560 And we want to check if this player's team is not equal to the dead team. 99 00:06:34,560 --> 00:06:38,610 So if they are on the alive team, then we don't care about them firing this event, we're just going 100 00:06:38,610 --> 00:06:40,350 to return out of the function. 101 00:06:40,440 --> 00:06:45,720 Otherwise what we can do is we can check if the action they supplied to us is equal to our camera manipulation. 102 00:06:45,720 --> 00:06:49,950 Enum dot two server dot change camera occlusion. 103 00:06:49,950 --> 00:06:54,900 So again remember inside of our camera manipulation handler we're firing to the server with the action 104 00:06:54,900 --> 00:06:56,220 change camera occlusion. 105 00:06:56,220 --> 00:06:59,670 And we're giving them the occlusion mode that we would like to change our camera to. 106 00:07:00,720 --> 00:07:05,220 Now, when we get past this action, the first thing we actually want to verify is the information coming 107 00:07:05,220 --> 00:07:05,820 from the client. 108 00:07:05,820 --> 00:07:10,530 Because an exploiter could be messing with whatever is inside of our ARGs table. 109 00:07:10,530 --> 00:07:15,210 Who knows, it could be passing whatever here, so we don't want to cause any errors on the server. 110 00:07:15,210 --> 00:07:19,920 We first want to verify the information being passed before we actually start acting on it. 111 00:07:19,920 --> 00:07:26,910 So what we could do is we could use our args matches type function in here, up here to verify the type 112 00:07:27,150 --> 00:07:30,930 of our args table and any value inside of our args table. 113 00:07:31,110 --> 00:07:38,400 So if arg matches type, we're going to pass args and check to see if this matches table. 114 00:07:38,580 --> 00:07:44,040 So if this does not match the argument of table then we're just going to return because we don't care 115 00:07:44,040 --> 00:07:45,030 about this player. 116 00:07:45,030 --> 00:07:48,930 They're obviously just goofing around with our remote event. 117 00:07:49,080 --> 00:07:54,420 Another thing we want to check is the type of our args occlusion mode. 118 00:07:54,940 --> 00:08:01,420 And if this is not equal to the type of enum item, then we obviously know that again, an exploiter 119 00:08:01,420 --> 00:08:04,570 is probably messing with our remote event, so we're just going to return. 120 00:08:04,780 --> 00:08:12,550 Otherwise, we want to make sure and check if the arg dot occlusion mode dot enum type is actually equal 121 00:08:12,550 --> 00:08:14,380 to the dev camera occlusion mode. 122 00:08:14,380 --> 00:08:20,650 So if it is not equal to the enum.dev camera occlusion mode, then again we probably have some exploiter 123 00:08:20,650 --> 00:08:23,290 messing with our remote, so we're going to return. 124 00:08:23,560 --> 00:08:28,780 Otherwise, once we have verified that all of the information passed here is correct on our player, 125 00:08:28,780 --> 00:08:35,380 we're going to set the dev camera occlusion mode equal to the args dot occlusion mode that was passed 126 00:08:35,380 --> 00:08:37,840 to our remote event, and that's all we need to do there. 127 00:08:38,440 --> 00:08:44,590 So back inside of our main guy handler, after we tell our camera manipulation handler to change our 128 00:08:44,590 --> 00:08:49,600 camera occlusion mode to the occlusion mode of Invisi cam, our camera should be able to pass through 129 00:08:49,600 --> 00:08:55,480 parts, which now means what we're going to do inside of our local player is set the property of camera 130 00:08:55,480 --> 00:08:59,200 max zoom distance equal to something we could do like seven studs. 131 00:08:59,200 --> 00:09:03,010 And we also want to change the camera minimum zoom distance. 132 00:09:03,010 --> 00:09:05,410 And we can reduce it to something like two studs. 133 00:09:05,410 --> 00:09:10,210 If we put it at 0.5, that means players can zoom all the way and go into first person mode, which 134 00:09:10,210 --> 00:09:10,990 we don't want. 135 00:09:10,990 --> 00:09:15,550 So instead we're giving them a little bit of a range that they can zoom in and out of to spectate the 136 00:09:15,550 --> 00:09:16,270 players. 137 00:09:16,450 --> 00:09:20,950 Otherwise, the next thing we would want to do is create a variable to get the player that we're currently 138 00:09:20,950 --> 00:09:21,460 spectating. 139 00:09:21,460 --> 00:09:23,860 So we can call this spectating player. 140 00:09:23,860 --> 00:09:29,230 And we would get it out of our live players table, and we would pass an index of the player that we're 141 00:09:29,230 --> 00:09:29,890 viewing. 142 00:09:29,890 --> 00:09:32,890 So we should create a variable actually up top here. 143 00:09:33,610 --> 00:09:38,560 And we can just call this variable something like, um, viewing player. 144 00:09:38,560 --> 00:09:43,330 And all this is going to do is keep track of the current index that we're currently viewing at. 145 00:09:43,330 --> 00:09:48,670 So when we get all of the alive players in the game and we hit the plus button to go to the next player, 146 00:09:48,670 --> 00:09:52,570 or we hit the minus button to go to the previous player, we're going to be updating the value inside 147 00:09:52,570 --> 00:09:58,930 of our viewing player variable, so we can go back down and we can pass viewing Player. 148 00:09:58,930 --> 00:10:04,210 And by default it's going to be number one or the first index within our live players table. 149 00:10:04,880 --> 00:10:09,470 And what we can do is we can refer to our current camera, and inside of there we want to change the 150 00:10:09,470 --> 00:10:17,300 camera subject property and set it equal to the spectating player dot character dot humanoid. 151 00:10:17,300 --> 00:10:22,610 Because by default, the camera subject is going to be set to our own player's character, but we want 152 00:10:22,610 --> 00:10:26,690 to change it to the other player's character that we're going to be spectating. 153 00:10:26,900 --> 00:10:33,080 After we do this, then we can go ahead and refer to our spectating frame, and there's a text label 154 00:10:33,080 --> 00:10:34,520 in there called name for player. 155 00:10:34,520 --> 00:10:38,480 And we want to change the text of that equal to the current player that we're spectating. 156 00:10:38,480 --> 00:10:40,400 So we'll just pass the name of that player. 157 00:10:41,230 --> 00:10:42,340 From this point. 158 00:10:42,340 --> 00:10:46,780 Another important thing we want to listen to is when this player gets jumpscared. 159 00:10:46,780 --> 00:10:50,740 So remember we set an attribute on that player when they get jumpscared. 160 00:10:50,740 --> 00:10:54,970 And when that happens, what we want to do is we want to stop spectating this player because they've 161 00:10:54,970 --> 00:10:55,810 just died. 162 00:10:55,810 --> 00:10:59,800 So that means we're going to have to listen on the spectating player. 163 00:10:59,800 --> 00:11:02,710 And we can use git attribute change signal. 164 00:11:02,710 --> 00:11:05,710 And the attribute we want to listen to is when they get jumpscared. 165 00:11:05,800 --> 00:11:08,470 And we can connect a function to this. 166 00:11:08,470 --> 00:11:16,990 And when this player gets jumpscared, we can um, have a function to, uh, basically change our camera 167 00:11:16,990 --> 00:11:22,810 to view a different player, or we can just have our camera directly view our AI monster squid, where 168 00:11:22,810 --> 00:11:25,030 that's roaming around the map, whatever is easier. 169 00:11:25,420 --> 00:11:29,290 So that means we're going to have to get the connection that gets returned from our connect function 170 00:11:29,290 --> 00:11:32,170 and disconnect and connect to this, uh, whenever. 171 00:11:32,170 --> 00:11:38,920 Because we don't want to constantly listen to this player every single time this, uh, attribute changes 172 00:11:38,920 --> 00:11:39,430 on them. 173 00:11:39,430 --> 00:11:46,300 So we could create a table and we're going to call this table, we could call it like viewing player 174 00:11:46,300 --> 00:11:50,710 connections, set it equal to a table, and then we can go back down. 175 00:11:51,210 --> 00:11:57,360 And then inside of our viewing player connections table, we can create a new key value pair. 176 00:11:57,360 --> 00:12:05,490 And the key for this would just be, um, our spectating player dot name equal to the spectating player. 177 00:12:05,490 --> 00:12:09,240 And we're going to be listening to when they're jumpscare attribute changes. 178 00:12:09,360 --> 00:12:15,810 And when that does we can have a function to control exactly what we want to do when our spectating 179 00:12:15,810 --> 00:12:16,590 player gets jumpscared. 180 00:12:16,590 --> 00:12:20,910 So we can call this function on spectating player jumpscared. 181 00:12:20,910 --> 00:12:22,800 So this will listen to when they die. 182 00:12:22,800 --> 00:12:25,290 And we can get the player that gets jumpscared here. 183 00:12:25,380 --> 00:12:30,480 And all we're going to do down here is just call our on spectating player jumpscared function and pass 184 00:12:30,480 --> 00:12:31,830 the spectating player. 185 00:12:32,340 --> 00:12:37,170 And what we can do in here is that after our spectating player gets jumpscared, we first want to check 186 00:12:37,170 --> 00:12:40,860 if they have a key value pair inside of our viewing player connections table. 187 00:12:40,860 --> 00:12:42,840 So we'll pass this player's name. 188 00:12:42,840 --> 00:12:47,850 So if they have a key in there, then what we need to do is refer to viewing player connections, pass 189 00:12:47,850 --> 00:12:53,940 player dot name and we want to disconnect the function on that is currently listening to. 190 00:12:53,940 --> 00:13:01,020 When their attribute changes, we disconnect that and then we want to change the player dot name inside 191 00:13:01,020 --> 00:13:02,130 of here equal to nil. 192 00:13:02,130 --> 00:13:04,770 So we get rid of that key value pair completely. 193 00:13:05,280 --> 00:13:09,660 And afterwards we want to refer to our current camera and change our camera subject. 194 00:13:10,620 --> 00:13:18,000 And what we could do is we could try to get all of the alive players that are currently in our game 195 00:13:18,000 --> 00:13:26,010 again and try to see if there's any left and set our camera subject to that, so we could get a live 196 00:13:26,010 --> 00:13:28,680 players from our Get Alive Players function. 197 00:13:29,460 --> 00:13:33,330 And basically we'll just set camera subject equal to. 198 00:13:33,420 --> 00:13:41,130 What we could do is check if the number of live players is actually greater than zero. 199 00:13:41,130 --> 00:13:47,850 So if number of live players is greater than zero, then what we could do is set our camera subject 200 00:13:47,850 --> 00:13:51,300 equal to a live players will pass one. 201 00:13:51,900 --> 00:13:54,930 Get their character and then get their humanoid. 202 00:13:55,200 --> 00:14:00,930 Otherwise, if we do not have any alive players left for some reason, then we can just set the camera 203 00:14:00,930 --> 00:14:07,260 subject of our camera equal to maybe, let's say, our Squidward that's roaming around the map. 204 00:14:07,350 --> 00:14:15,120 So inside of the workspace characters folder, we can find First Child, which would be our handsome 205 00:14:15,120 --> 00:14:19,860 Squidward AI, and we can go ahead and get his humanoid. 206 00:14:20,640 --> 00:14:26,610 So if this condition evaluates to true right here, then the spectating player is going to be whoever's 207 00:14:26,610 --> 00:14:27,420 left alive. 208 00:14:27,450 --> 00:14:32,340 Otherwise, if there is nobody that's left alive, then the other spectating person we're going to be 209 00:14:32,340 --> 00:14:35,820 viewing is our handsome Squidward. 210 00:14:36,720 --> 00:14:40,440 So the next thing we can do is refer to our spectate frame. 211 00:14:40,950 --> 00:14:45,990 And set name for player dot text equal to. 212 00:14:45,990 --> 00:14:48,030 And again we're going to copy this. 213 00:14:48,030 --> 00:14:52,680 If the number of alive players is greater than zero, that means we can go ahead and set the text equal 214 00:14:52,680 --> 00:14:54,750 to the name of that spectating player. 215 00:14:54,750 --> 00:15:01,170 So that means we can put an and statement here, get a live players number one and then just get their 216 00:15:01,170 --> 00:15:01,830 name. 217 00:15:02,460 --> 00:15:06,690 Or we'll just set the name equal to something like Squidward. 218 00:15:07,570 --> 00:15:10,360 So if there's any live players left, we spectate that. 219 00:15:10,360 --> 00:15:13,420 A live player, we set the text equal to their name. 220 00:15:13,420 --> 00:15:18,400 Otherwise instead we just go ahead and spectate our Squidward that's roaming around the map. 221 00:15:18,700 --> 00:15:22,900 And then once that's done, we can set viewing player equal to one. 222 00:15:23,170 --> 00:15:26,050 And I think that's all we need to do for this function. 223 00:15:26,800 --> 00:15:32,290 So I think the next important things that we're going to have to do is listen to when we press different 224 00:15:32,290 --> 00:15:34,510 buttons within our spectating frame. 225 00:15:34,510 --> 00:15:38,740 So for example, if we want to spectate the next player, then we'll spectate the next player. 226 00:15:38,740 --> 00:15:42,040 If we want to spectate the previous player then we'll spectate the previous player. 227 00:15:42,520 --> 00:15:47,350 So when we click the next button inside of our spectating frame to move to the next player, the first 228 00:15:47,350 --> 00:15:50,770 thing we of course need to check is whether or not we have any alive players left. 229 00:15:50,770 --> 00:15:53,470 So we're going to get the current alive players. 230 00:15:53,740 --> 00:15:58,390 And if the number of alive players that we have is, let's say, equal to zero, then we're just simply 231 00:15:58,390 --> 00:16:01,720 going to return because we don't care about them hitting the next button. 232 00:16:02,110 --> 00:16:07,120 Otherwise, what we could do is refer to viewing player and increment it by one. 233 00:16:07,360 --> 00:16:13,000 And if the viewing player's value becomes greater than the number of alive players, then all we're 234 00:16:13,000 --> 00:16:15,670 going to do is set viewing player equal to one. 235 00:16:15,670 --> 00:16:21,220 So if we keep clicking the next button, eventually we'll want to reset it and put it back at the value 236 00:16:21,220 --> 00:16:21,970 of one. 237 00:16:22,360 --> 00:16:28,720 And then we can get the spectating player, which is equal to our live player's, and get whatever player 238 00:16:28,720 --> 00:16:30,850 at the current viewing player index. 239 00:16:31,490 --> 00:16:36,590 And then inside of our current camera, we'll set the camera subject property equal to the spectating 240 00:16:36,590 --> 00:16:37,370 player. 241 00:16:37,400 --> 00:16:39,680 Dot character dot humanoid. 242 00:16:41,730 --> 00:16:47,610 And then we're also going to update our spectate frame dot name for player dot text equal to the spectating 243 00:16:47,610 --> 00:16:48,570 player's name. 244 00:16:51,300 --> 00:16:56,580 And then from this point, we actually want to do the exact same thing that we did inside of this function 245 00:16:56,580 --> 00:16:56,790 here. 246 00:16:56,790 --> 00:17:00,120 We want to listen for when this player dies. 247 00:17:00,120 --> 00:17:05,610 So we'll just copy this, paste this down here we get the spectating player and listen for when they 248 00:17:05,610 --> 00:17:06,330 are jumpscared. 249 00:17:06,330 --> 00:17:09,210 And when that happens then we move on to the next player. 250 00:17:09,810 --> 00:17:14,910 Otherwise we can just basically copy all of this and do the exact same thing when we hit the previous 251 00:17:14,910 --> 00:17:20,970 button, but instead this time we want to decrement our viewing player value by one, and we want to 252 00:17:20,970 --> 00:17:28,860 ensure that if our viewing player number becomes, let's say, less than the number of live players, 253 00:17:28,860 --> 00:17:34,410 then we can set our viewing player value equal to the number of alive players. 254 00:17:34,410 --> 00:17:39,510 So basically, if we keep decreasing the value, eventually we go back to the top and then continue 255 00:17:39,510 --> 00:17:40,950 decreasing from that point. 256 00:17:41,880 --> 00:17:46,980 Other than that, we do the exact same thing by changing the camera subject equal to the current spectating 257 00:17:46,980 --> 00:17:50,730 player, and we listen for when that spectating player gets jumpscared. 258 00:17:50,910 --> 00:17:55,380 So I believe now that's actually everything we needed to do for our spectating system. 259 00:17:55,380 --> 00:18:01,440 The only thing left to do is actually test it by going to the test tab and starting a server with multiple 260 00:18:01,440 --> 00:18:02,460 different players in there. 261 00:18:02,460 --> 00:18:06,570 That way, we can actually fully test out whether or not our spectating system is working or not. 262 00:18:06,570 --> 00:18:08,940 So let's go ahead and test this out and I'll see you there. 263 00:18:10,190 --> 00:18:10,610 All right. 264 00:18:10,610 --> 00:18:15,590 As you can see, I've got my three player test set up and I'm about to enter the basement, which should 265 00:18:15,590 --> 00:18:17,480 teleport all of my players down there. 266 00:18:17,480 --> 00:18:18,410 Beautiful. 267 00:18:19,900 --> 00:18:25,600 And basically I'm going to have one of my guys hide inside of a locker to see if we can actually spectate 268 00:18:25,600 --> 00:18:25,870 him. 269 00:18:25,870 --> 00:18:28,300 So we'll put this guy inside of a locker. 270 00:18:28,930 --> 00:18:31,930 And then for this guy, we could also put him inside of a locker as well. 271 00:18:31,930 --> 00:18:36,370 Let me actually just pick up this flashlight off the floor real quick, and then let me slap this guy 272 00:18:36,370 --> 00:18:37,300 inside of a locker. 273 00:18:38,200 --> 00:18:43,330 And then with this guy, we're just going to have this guy here on the right die and see if we can actually 274 00:18:43,330 --> 00:18:46,270 spectate these players that are currently inside of these lockers. 275 00:18:46,270 --> 00:18:52,810 So that means we should go look for our Squidward and have him kill us just to see if we get the spectating 276 00:18:52,810 --> 00:18:53,470 system open. 277 00:18:56,590 --> 00:18:57,130 There we go. 278 00:18:57,130 --> 00:19:00,820 We died and hopefully we should start spectating and perfect. 279 00:19:00,820 --> 00:19:03,850 It says we are currently spectating player number two. 280 00:19:03,880 --> 00:19:06,640 As you can see, we are able to look around him. 281 00:19:06,640 --> 00:19:10,660 And since we change the occlusion mode of the camera, as you can see, when I pass my camera through 282 00:19:10,660 --> 00:19:15,280 this wall, it becomes transparent and we can go ahead and look around at our player. 283 00:19:15,280 --> 00:19:16,120 Perfect. 284 00:19:16,120 --> 00:19:18,790 And if I hit the next button, we should move to the next player. 285 00:19:18,790 --> 00:19:19,360 There we go. 286 00:19:19,360 --> 00:19:20,230 We're at player number three. 287 00:19:20,230 --> 00:19:22,600 And if I hit this again it should go back to the other player. 288 00:19:22,600 --> 00:19:23,440 Perfect. 289 00:19:23,440 --> 00:19:25,630 So our spectating system is working great. 290 00:19:25,840 --> 00:19:30,130 The next thing we need to check is when our spectating player gets jumpscared. 291 00:19:30,130 --> 00:19:34,060 So this guy inside of the locker here, what we're going to do is we're going to have him hop out and 292 00:19:34,060 --> 00:19:38,140 let's see what happens to our spectating system when this guy gets jumpscared. 293 00:19:38,200 --> 00:19:43,630 So we go back to this guy and we're going to exit the locker and let me grab the flashlight off the 294 00:19:43,630 --> 00:19:44,560 floor right here. 295 00:19:46,390 --> 00:19:50,980 And we're going to look around, try to find the Squidward to jumpscare us. 296 00:19:52,820 --> 00:19:54,830 As you can see, it looks great on our spectating system. 297 00:19:54,830 --> 00:19:57,890 We can actually see the entire map because we have our night vision on. 298 00:19:59,420 --> 00:20:01,460 But let me try to find the Squidward here real quick. 299 00:20:02,060 --> 00:20:03,440 I think I hear him over here somewhere. 300 00:20:07,430 --> 00:20:09,020 Where are you at, Squidward? 301 00:20:11,300 --> 00:20:11,960 There he is! 302 00:20:11,960 --> 00:20:13,760 So let's get Jumpscared and see what happens. 303 00:20:20,120 --> 00:20:25,520 So he did get jump scared and we did move our player back to the other spectating player. 304 00:20:25,520 --> 00:20:29,900 But of course there looks like there was a little bit of a delay there. 305 00:20:29,900 --> 00:20:30,770 I'm not sure why. 306 00:20:30,800 --> 00:20:34,880 Maybe we accidentally set the attribute of jump scared a little too late on the player. 307 00:20:34,880 --> 00:20:40,400 So what we can do is we can check to see when we set that attribute on the player when they get jump 308 00:20:40,400 --> 00:20:40,970 scared. 309 00:20:40,970 --> 00:20:45,260 But other than that, it appears that our spectating system is actually working quite well. 310 00:20:45,260 --> 00:20:51,890 So the last thing we can do here is have this guy die and see what happens to our spectating system. 311 00:20:51,890 --> 00:20:56,990 So we're going to have him come out of the locker, turn on his light and let's have him walk around. 312 00:21:01,550 --> 00:21:02,270 All right. 313 00:21:05,550 --> 00:21:06,450 And there we go. 314 00:21:06,450 --> 00:21:12,870 As you can see, our spectating system appears to have moved back to Squidward here, but unfortunately, 315 00:21:12,870 --> 00:21:17,280 it does appear that our spectating system for this guy hasn't moved back. 316 00:21:17,670 --> 00:21:23,100 So let's go ahead and figure out why exactly the spectating system didn't work for our other guy. 317 00:21:23,100 --> 00:21:25,590 There might be a little bit of an error in our logic. 318 00:21:27,170 --> 00:21:31,940 Okay, so I think a better system that we could do for our spectating system is have our spectating 319 00:21:31,940 --> 00:21:37,850 player variable be a global variable in our entire script, and instead update this variable each time 320 00:21:37,850 --> 00:21:43,160 we change the player that we're spectating when we hit the previous or next button. 321 00:21:43,160 --> 00:21:47,120 And we want to do this to check if we had any previous connections on them. 322 00:21:47,120 --> 00:21:51,800 And when we go to spectate the next player, we want to disconnect any of those previous connections 323 00:21:51,800 --> 00:21:54,080 because we're no longer spectating that particular player. 324 00:21:54,080 --> 00:21:57,980 So what we can do is we can copy this here and I'll go back up. 325 00:22:00,200 --> 00:22:04,910 And what we'll do is we'll create this variable up here and we're not going to initialize it to anything, 326 00:22:04,910 --> 00:22:07,100 or we can just set it to nil as default. 327 00:22:07,100 --> 00:22:08,420 And then we can go back down. 328 00:22:08,940 --> 00:22:14,760 And what we can do here is we can update our spectating player equal to the current alive players. 329 00:22:14,760 --> 00:22:16,980 So again we'll do that down here as well. 330 00:22:16,980 --> 00:22:22,350 And before we change our spectating player we want to do is we want to check if there was a previous 331 00:22:22,350 --> 00:22:23,220 spectating player. 332 00:22:23,220 --> 00:22:28,020 So if we had a previous spectating player before we update the variable, we want to check if the spectating 333 00:22:28,020 --> 00:22:31,350 player has a key value pair inside of our viewing player connections table. 334 00:22:31,350 --> 00:22:36,810 So if viewing player connections table, we pass spectating player dot name. 335 00:22:37,940 --> 00:22:39,890 Then we will want to disconnect that. 336 00:22:39,890 --> 00:22:45,290 So we'll copy this, paste that in there, disconnect that and then paste it again and set it equal 337 00:22:45,290 --> 00:22:45,830 to nil. 338 00:22:45,830 --> 00:22:51,920 And then we can copy this right here and do the exact same thing for our next script here. 339 00:22:52,720 --> 00:22:57,010 So we update our spectating player to disconnect any previous spectating. 340 00:22:57,010 --> 00:23:01,210 And then we also want to do the exact same thing when we actually start spectating. 341 00:23:01,210 --> 00:23:04,690 So we're going to set spectating players equal to this. 342 00:23:04,690 --> 00:23:09,640 And we're also going to check if there was a previous spectating player just in case. 343 00:23:10,180 --> 00:23:14,020 And now that means inside of our own spectating player Jumpscared function. 344 00:23:14,020 --> 00:23:18,700 It's not going to work very well when we change our camera subject to spectate a different player. 345 00:23:18,700 --> 00:23:22,540 And this is because we're not listening to this particular player when they get jumpscared. 346 00:23:22,540 --> 00:23:26,980 And that's not possible to do because we're doing it within this function itself. 347 00:23:26,980 --> 00:23:33,580 So to avoid this kind of conundrum, what we could do is just set the camera subject directly to our 348 00:23:33,580 --> 00:23:37,450 Squidward instead, and instead just set the text equal to Squidward. 349 00:23:37,450 --> 00:23:43,660 And we don't have to sit there and worry about our current viewing player, so we'll just do that instead 350 00:23:43,660 --> 00:23:47,050 and have our current spectating player at our Squidward. 351 00:23:47,440 --> 00:23:51,910 And then we can also actually just keep our viewing player and reset that value back to one. 352 00:23:51,910 --> 00:23:55,990 So that way if our player doesn't want to spectate Squidward, then they can hit the next button or 353 00:23:55,990 --> 00:24:01,150 the previous button on their spectating frame, and that way it actually moves to the next player. 354 00:24:01,840 --> 00:24:07,060 And because we're moving to the next player, we're actually able to listen for when that particular 355 00:24:07,060 --> 00:24:08,620 player gets jumpscared. 356 00:24:09,040 --> 00:24:11,410 So now this system actually should be working quite good. 357 00:24:11,410 --> 00:24:16,570 Now we can go ahead and start up another three player server and see if our spectating system is working 358 00:24:16,600 --> 00:24:17,380 fine. 359 00:24:18,340 --> 00:24:18,700 All right. 360 00:24:18,700 --> 00:24:19,930 We got everything set up again. 361 00:24:19,930 --> 00:24:22,750 We got our two guys chilling inside of their lockers. 362 00:24:22,750 --> 00:24:27,310 So what we're going to do now is have our guy in the center here die and see if we can go ahead and 363 00:24:27,310 --> 00:24:29,200 start spectating those dudes in the lockers. 364 00:24:29,200 --> 00:24:31,330 So we'll try to find Squidward here. 365 00:24:34,060 --> 00:24:34,720 There he is. 366 00:24:38,110 --> 00:24:38,590 All right. 367 00:24:38,590 --> 00:24:41,050 We have died, and let's see if we start spectating. 368 00:24:41,320 --> 00:24:41,620 Okay. 369 00:24:41,620 --> 00:24:42,040 Perfect. 370 00:24:42,040 --> 00:24:43,750 Here we are spectating player number two. 371 00:24:43,750 --> 00:24:46,630 And we can switch between these two different players. 372 00:24:46,630 --> 00:24:47,920 So. 373 00:24:50,460 --> 00:24:55,950 It does look like when I go down and hit the previous button, I'm not moving to the next player, which 374 00:24:55,950 --> 00:24:57,720 is actually kind of interesting. 375 00:24:58,920 --> 00:25:03,930 So we'll obviously have to figure out why our left button isn't working, but that's just a little minor 376 00:25:03,930 --> 00:25:04,200 arrow. 377 00:25:04,230 --> 00:25:09,840 We can fix in a moment, but let's have um, I actually don't know which guys and which locker. 378 00:25:09,840 --> 00:25:12,120 Let's see if we can have this guy come out of his locker. 379 00:25:12,240 --> 00:25:12,810 There we go. 380 00:25:13,560 --> 00:25:16,500 Let's have this guy die and see what happens. 381 00:25:16,500 --> 00:25:22,230 So we're going to have him roam around and he'll run down here. 382 00:25:22,230 --> 00:25:24,090 We're trying to find Squidward here. 383 00:25:24,720 --> 00:25:25,590 There he is. 384 00:25:27,030 --> 00:25:29,700 Oh, fortunately, he did disappear, but he's coming back. 385 00:25:31,580 --> 00:25:34,940 There we go and we immediately start spectating our Squidward friend here. 386 00:25:34,940 --> 00:25:35,570 Perfect. 387 00:25:37,880 --> 00:25:40,460 So it doesn't look like we have any problems with that. 388 00:25:40,460 --> 00:25:43,580 And if we hit the next button, we should go to our other player. 389 00:25:43,580 --> 00:25:44,570 And there we go. 390 00:25:44,570 --> 00:25:46,970 We're back to player number three chilling inside of our locker. 391 00:25:46,970 --> 00:25:49,130 So let's go ahead and have this guy die. 392 00:25:49,310 --> 00:25:51,410 So we'll have him exit out of the locker. 393 00:25:54,630 --> 00:25:56,010 Have him look around the map. 394 00:26:00,810 --> 00:26:02,040 And let's see what happens. 395 00:26:03,650 --> 00:26:04,190 Perfect. 396 00:26:04,430 --> 00:26:06,620 And now all of our players are spectating. 397 00:26:06,620 --> 00:26:09,440 Squidward, everything is working well. 398 00:26:09,440 --> 00:26:14,480 We don't need to worry about our last guy not spectating anyone, because by this point, all of the 399 00:26:14,480 --> 00:26:20,510 players in our game have died and that means we would have to, you know, end the game because everybody 400 00:26:20,510 --> 00:26:21,890 died, everybody failed. 401 00:26:22,220 --> 00:26:23,930 That should actually be pretty easy to do. 402 00:26:23,930 --> 00:26:28,520 All we would have to do is listen for when the number of players on our live team reaches zero, and 403 00:26:28,520 --> 00:26:31,160 then we would teleport all of our players back to the lobby. 404 00:26:31,310 --> 00:26:33,140 So actually, let's go ahead and do that real quick. 405 00:26:33,140 --> 00:26:38,090 And let's also fix our, uh, little left button that's not resetting correctly. 406 00:26:39,460 --> 00:26:44,980 Okay, so in our previous button here inside of the lambda function, I think our problem is we are 407 00:26:44,980 --> 00:26:48,310 comparing the viewing player number to the wrong value here. 408 00:26:48,310 --> 00:26:53,080 Instead of looking at the maximum number of alive players, we just need to pay attention to when our 409 00:26:53,080 --> 00:26:58,510 viewing player number goes below one, which is the minimum index that we can have when our viewing 410 00:26:58,510 --> 00:27:00,010 player number goes below one. 411 00:27:00,010 --> 00:27:03,520 Then we set the viewing player number equal to the number of alive players. 412 00:27:03,520 --> 00:27:06,160 So that should fix our problem right there. 413 00:27:06,340 --> 00:27:11,350 And then the other thing we can go ahead and script is when all the players in our game die, we can 414 00:27:11,350 --> 00:27:13,420 go ahead and teleport all of them back to the lobby. 415 00:27:13,420 --> 00:27:19,720 So what we could do is we could go to our game service, and inside of here we can just scroll down 416 00:27:19,720 --> 00:27:25,960 and inside of the initialize section, what we can do is we can create a little section to listen for 417 00:27:25,960 --> 00:27:29,650 when all of our players have died. 418 00:27:29,650 --> 00:27:35,110 So what we could do is create a section here to listen for the live team. 419 00:27:35,110 --> 00:27:39,340 When a player is removed and we'll connect a lambda function to this. 420 00:27:39,340 --> 00:27:45,070 And all we can do is check if the number of people in the alive team get players. 421 00:27:45,070 --> 00:27:50,680 If the number of people in there is zero, so everybody has died, then we can just simply call our 422 00:27:50,680 --> 00:27:56,710 teleport losing players to lobby function, which will handle everything else for us by displaying on 423 00:27:56,710 --> 00:28:01,030 the screen that everybody failed, and then we teleport them back to the lobby. 424 00:28:01,180 --> 00:28:03,730 So that should be good to go there. 425 00:28:03,730 --> 00:28:06,730 And our spectating system should also be complete and fixed up. 426 00:28:06,730 --> 00:28:10,420 So let's go ahead and test this out one more time to verify that everything is working. 427 00:28:11,380 --> 00:28:12,010 Okay. 428 00:28:12,010 --> 00:28:14,440 So I got my two guys back in their lockers again. 429 00:28:14,440 --> 00:28:17,410 And we're going to get our center guy here to die. 430 00:28:20,650 --> 00:28:21,460 All right, we're dead. 431 00:28:21,460 --> 00:28:23,470 Hopefully we start spectating now. 432 00:28:23,470 --> 00:28:24,340 And there we go. 433 00:28:24,340 --> 00:28:24,850 We're spectating. 434 00:28:24,850 --> 00:28:27,520 Player one move to the next, player spectating player two. 435 00:28:27,520 --> 00:28:28,900 And we can switch between them. 436 00:28:28,900 --> 00:28:31,960 And then it should work the same way when we click the previous button. 437 00:28:31,960 --> 00:28:35,350 So we click that and perfect we're moving between the two players. 438 00:28:35,350 --> 00:28:39,310 So let's go ahead and go to player number two and check to see when he dies. 439 00:28:39,310 --> 00:28:45,940 So when we go and exit the locker and we look around we're roaming around, see if we can try to get 440 00:28:45,940 --> 00:28:47,470 us to die here. 441 00:28:54,590 --> 00:28:54,800 Okay. 442 00:28:54,800 --> 00:28:55,310 Perfect. 443 00:28:55,310 --> 00:29:00,470 We are spectating Squidward here, watching him roam around, and if we click, we should move to the 444 00:29:00,470 --> 00:29:01,100 next player. 445 00:29:01,100 --> 00:29:02,060 Which we do. 446 00:29:02,060 --> 00:29:06,110 And our other guy is also successfully spectating this guy as well. 447 00:29:06,110 --> 00:29:08,990 So let's go ahead and have him exit the locker. 448 00:29:09,140 --> 00:29:15,470 And when this guy dies right here, we should end the game because all of the players are dead. 449 00:29:15,470 --> 00:29:17,510 So let's go ahead and see what happens. 450 00:29:17,810 --> 00:29:23,450 We're going to have this guy roam around, try to find Squidward here and here. 451 00:29:23,450 --> 00:29:25,070 I'm not sure where he's at. 452 00:29:26,660 --> 00:29:28,220 I think we're getting close to him here. 453 00:29:29,450 --> 00:29:30,050 Areas. 454 00:29:33,010 --> 00:29:35,020 And there we go. 455 00:29:35,530 --> 00:29:37,000 Everybody is dead. 456 00:29:37,000 --> 00:29:37,720 You failed. 457 00:29:37,720 --> 00:29:39,370 Unfortunately, you failed to win this time. 458 00:29:39,370 --> 00:29:39,970 Don't give up. 459 00:29:39,970 --> 00:29:40,810 Try again. 460 00:29:40,990 --> 00:29:43,030 So all of our players failed. 461 00:29:43,030 --> 00:29:45,760 Of course, we can't teleport while we were in testing. 462 00:29:45,760 --> 00:29:47,770 But as you can see, everything's working great. 463 00:29:48,250 --> 00:29:51,100 Everybody dies, the game ends. 464 00:29:51,100 --> 00:29:54,760 And our spectating system so far is seeming to work great. 465 00:29:54,760 --> 00:30:00,220 So the next thing we need to fill out in our spectating system is giving the ability for players to 466 00:30:00,220 --> 00:30:02,590 respawn and for them to respond. 467 00:30:02,590 --> 00:30:08,020 They can click that respawn button inside of the spectating system, which will prompt them to purchase 468 00:30:08,020 --> 00:30:09,820 a developer product to respawn. 469 00:30:09,820 --> 00:30:12,190 And that's what we're going to do in the next lecture. 470 00:30:12,190 --> 00:30:14,260 So we'll go ahead and see you there.